home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 41
/
Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso
/
Aminet
/
util
/
rexx
/
cdmp.lha
/
cdmp.rx
< prev
Wrap
Text File
|
2000-11-26
|
29KB
|
973 lines
/**********************************************************************************************************************
$VER: cdmp.rx v1.2 (18.11.2000)
Erstellt: J.Klingele 03.2000
Email: jklingele@gmx.de
liest tracks (titel) von cd und wandelt diese ins mp3 format
benötigt cdda zum einlesen der CD
und lame zum erzeugen der mp3 files
Beide im Suchpfad (vorzugsweise c:)
V1.0 10.08.2000 - 1. vollständige, inoffizielle Version - jk
V1.1 26.08.2000 - Unterstützung von CDID's, bessere Fehlerbehandlung und Kontrolle, Parameter für mp3-extension
1. Aminet Release - jk
V1.2 25.11.2000 - Unterstützung von Pegase, Stackanpassung für PPC-Lame, Default-Name für Worksheets, eigenes Window
für CD-Inhalt (Option), kleinere Bugfixes, 2.Aminet Release - jk
***********************************************************************************************************************/
/******* Globale Parameter Variablen *******/
titelpfad = "CD-A:" /* Pfad zum speichern der tracks und sonstiger datenfiles, MUSS mit : oder / enden */
mp3pfad = "MP3:" /* Pfad zum speichern der mp3-files, MUSS mit : oder / enden */
cdid_dir = "CDID:" /* Pfad zu den CDID's */
titellist = "titelliste" /* Dateiname zum abspeichern der eingegeben Titel, wird für Restore benutzt */
cdlist = "ram:cdliste" /* Dateiname der Titelliste von cdda, wird nut temporär zum einlesen verw. */
mp_ext = ".mp3" /* extension für mp3-Dateien */
cdsave = "CDsave" /* Default Name der für spätere Bearbeitung abgespeicherten Listen bei CD ohne ID */
plan = "e" /* cdda-Modus e=atapi */
list_win = 0 /* CD-Inhaltsverzeichnis in einem eigenen Fenster anzeigen? 0=nein 1=ja */
lw_xs = 150 /* linke obere Ecke des CD-Inhaltsverzeichnis Fensters Horizontale (x) Position */
lw_ys = 10 /* linke obere Ecke des CD-Inhaltsverzeichnis Fensters Vertikale (y) Position */
lw_fw = 9 /* Breite des verwendeten Shell Fonts +1 (topaz 8=9, 11=9) */
lw_fh = 12 /* Höhe des verwendeten Shell Fonts +1 (topaz 8=9, 11=12) */
encoder = "lame" /* gewünschter encoder, "lame" oder "pegase" (lowercase!!) */
lameopt = "-b 160" /* optionstring für lame */
pegaseopt = "LAYER 2 BITRATE 160" /* optionstring for pegase */
lame_ppc = 1 /* PPC-Version von Lame im Einsatz? 0=nein 1=ja */
ppc_stack = 200000 /* Stackwert für PPC-Lame */
debug = 0 /* Debugmode und -anzeige? 0=nein 1=ja */
del_titel = 1 /* CD-Titel nach Konvertierung löschen? 0=nein 1=ja */
bpb = 2352 /* Bytes per Block ca. Wert */
skip_lo = 150 /* Anzahl der Blocks die vom Leadout abgezogen werden. 1s ca. 75 Blocks (2s) */
repl_spc = 1 /* Bei Eingabe der CD-Titelnamen Leerzeichen durch '_' ersetzen 0=nein 1=ja */
max_name_len = 30 /* max. Dateinamenlänge ffs=30 Zeichen */
dirty_char = '~%#?<>|()[]":`;*' /* ungültige Zeichen die bei der Namenseingabe ersetzt werden müssen. */
/*******************************************
Sonstige Globale Variablen
{ cd. - Stammvariable mit den Daten der einzelnen Titel auf CD
cd.titel. - Daten eines titels
cd.titel.nr - Titelnummer
.name - Titelname
.ip - Interpret
.cdn - Dateiname (ohne Pfad) zum abspeichern auf HD
.start - Startblock
.ende - Endblock
.laenge - Laenge in Blocks
.zeit - Spielzeit
}
{ rip. - Stammvariable mit Daten der abzuspeichernden und umzuwandelnden Titel
rip.titel. - Daten eines titels
rip.titel.cdt - (CD) Titelnummer (dient als Verweis auf cd.titel.nr)
.mpn - mp3 Dateiname zum abspeichern
.cut_lo - zusätzlicher Abzug vom lead-out (optional per eingabe)
}
anz_titel - Anzahl der Titel auf CD
anz_save - Anzahl der Titel die eingelesen werden sollen
mp3 - mit mp3 Konvertierung j/n
restore - restorefunktion, alte Daten verwenden j/n
listname - übergebener dateiname bei Programmaufruf, sollte bestehende Titelliste enthalten
list_in - dateiname zum einlesen einer titelliste (wird entw. auf titellist oder listname gesetzt)
cdid - ID String der CD im Laufwerk
cdid_rest - ID String der zu bearbeitenden CD bei restore
Lokale Variablen
a, b, c, akt_t, datei_in, datei_out, cdnr, zeile, gr, cut, temp, dummy
'Lokale' Variablen in Unterprogrammen
sdatei, sstart, sende, sa, s_name, s_len
*********************************************/
SIGNAL ON break_c /* abbruch bei CTRL-C */
SIGNAL ON failure /* abbruch bei Host-Fehler */
OPTIONS FAILAT 10
anz_titel = -1
anz_save = -1
mp3 = "N"
IF EXISTS(cdid_dir) THEN
cdid_mode = 1
ELSE
cdid_mode = 0
/** 1. Programmstart mit restore einer gespeicherten Sitzung ? **/
/* Dateiname zu bestehender Titelliste übergeben ? */
PARSE ARG listname
IF listname ~== "" THEN
list_in = titelpfad||listname
ELSE
list_in = titelpfad||titellist /* ohne Übergabeparameter wird der Standardname fürs Backup verwendet */
IF debug == 1 THEN SAY "<"listname">"
/** 1a. Prüfen ob Bearbeitung zuvor unterbrochen wurde **/
IF EXISTS(list_in) THEN DO
/* alte Werte wieder einlesen */
OPEN(datei_in,list_in,R)
a = 0
rip. = ""
cdid_rest = READLN(datei_in)
mp3 = READLN(datei_in)
DO WHILE ~eof(datei_in)
a = a +1
rip.a.cdt = READLN(datei_in)
rip.a.mpn = READLN(datei_in)
rip.a.cut_lo = READLN(datei_in)
IF debug == 1 THEN
SAY "ID: "cdid_rest" - MP3: "mp3" - Titel "a": "rip.a.cdt" - Dateiname : "rip.a.mpn" Abzug : "rip.a.cut_lo
END /* do while */
CLOSE(datei_in)
a = a -1 /* Da das Dateiende hinter der letzen Zeile ist gibts immer einen leeren Satz */
/* Daten vorhanden ?? (>>>>>> evt. mal durch irgendeine Checksumme ersetzen) */
IF (rip.a.cdt ~== "") & (RIGHT(rip.a.mpn,4) == mp_ext) THEN DO
/* Variablen für nachfolgende Routinen setzen */
anz_save = a
SAY
IF mp3 == "J" THEN DO
SAY "> Alte Angaben eingelesen, folgende MP3-files sollen erzeugt werden:"
SAY
SAY " CD-Titel | MP3-Name | kürzen um"
SAY "-------------------------------------------------------"
DO a = 1 to anz_save
SAY INSERT('','',0,6-(rip.a.cdt > 9),' ')||rip.a.cdt" - "rip.a.mpn||INSERT(' ','',1,max_name_len - LENGTH(rip.a.mpn),' ')"- " (skip_lo + rip.a.cut_lo) % 75"s."
END /* Do */
END /* if mp3 */
ELSE DO
SAY "> Alte Angaben eingelesen, folgende CD-files sollen erzeugt werden:"
SAY
SAY " CD-Titel"
SAY "----------"
DO a = 1 to anz_save
SAY INSERT('','',0,5-(rip.a.cdt > 9))||rip.a.cdt
END /* Do */
END /* else - if mp3 */
SAY
/* Wenn ja, ermitteln ob die alte Sitzung fortgesetzt werden soll */
IF list_in == titelpfad||titellist THEN DO
SAY "> Soll die abgebrochene Bearbeitung der letzten CD"
WRITECH(stdout,"> mit diesen Daten weitergeführt werden (j/N)? ")
END
ELSE DO
SAY "> Soll die Bearbeitung mit diesen Daten von <"listname">"
WRITECH(stdout,"> begonnen werden (j/N)? ")
END
PULL restore
IF restore == "J" THEN DO
/* CD-Liste wird auf alle Fälle wieder neu eingelesen, sicher ist sicher */
CALL get_toc()
DO WHILE cdid ~== cdid_rest /* warten bis richtige CD eingelegt wurde */
SAY
SAY "> ACHTUNG !! Falsche CD, unbedingt wieder die passende CD einlegen"
SAY "> und mit Return bestätigen."
PULL temp /* auf Return warten */
CALL get_toc()
END /* do while */
END /* if restore */
ELSE DO
restore = "N" /* restore und anz_save auf definierten Wert setzen sonst gibts evt. Probleme */
anz_save = 0
END
END /* if rip.. */
ELSE DO /* Notbremse bei Fehler */
SAY "> Daten der letzen Bearbeitung konnten nicht eingelesen werden."
SAY "> Wahrscheinlich ist die Datei "list_in" defekt. :-("
SAY "> Hilft nichts, alles nochmal neu eingeben ;-)"
restore = "N"
anz_save = 0
mp3 = "N"
END /* else - if rip.. */
END /* if exists */
/** 1b. Inhaltsverzeichnis einlesen und auswerten **/
IF (restore ~== "J") THEN DO /* aber nicht wenn eine Sitzung fortgeführt wird */
CALL get_toc()
IF (anz_titel > 0) THEN DO
SAY
SAY "> CD Inhalt eingelesen, insgesamt "anz_titel" Titel:"
IF cdid_mode == 1 THEN DO
li = 10 /* mindestlaenge interpret (wegen text) */
ln = 6 /* mindestlaenge titel */
DO a = 1 to anz_titel
IF LENGTH(cd.a.ip) > li THEN li = LENGTH(cd.a.ip)+1 /* min.laenge interpret anpassen wenn länger */
IF LENGTH(cd.a.name) > ln THEN ln = LENGTH(cd.a.name)+1 /* min.laenge titel anpassen wenn länger */
END /* do a */
b = " Titel | Interpret"INSERT('','',0,li-9,' ')"| Titel"INSERT('','',0,ln-5,' ')"| Länge " /* Länge des Headers */
IF list_win == 1 THEN DO /* Inhalt in eigenem Fenster darstellen ? ... */
c = (LENGTH(b)+4)*lw_fw
d = (anz_titel+8)*lw_fh
OPEN(lw,'CON:'lw_xs'/'lw_ys'/'c'/'d'/CD-List')
END
ELSE /* ... nöö */
OPEN(lw,"*")
WRITELN(lw,"CD-Interpret: "cd.0.ip)
WRITELN(lw,"CD-Titel : "cd.0.name)
WRITELN(lw,'')
WRITELN(lw,b)
WRITELN(lw,INSERT('','',1,LENGTH(b)+2,'-'))
DO a = 1 to anz_titel /* titel ausgeben */
WRITELN(lw, INSERT('','',0,4-(a > 9),' ')||cd.a.nr" - "cd.a.ip||INSERT('','',0,li-LENGTH(cd.a.ip),' ')"- "cd.a.name||INSERT('','',0,ln-LENGTH(cd.a.name),' ')"- "cd.a.zeit)
END /* do a */
WRITELN(lw, INSERT('','',0,LENGTH(b)+3,'-'))
WRITELN(lw, INSERT('','',0,li+ln+5,' ')"Gesamt: "cd.a.zeit)
END /* if cdid_mode */
ELSE DO /* keine cdid vorhanden, daher auch keine titelnamen */
IF list_win == 1 THEN DO
c= 21*lw_fw
d= (anz_titel+6)*lw_fh
OPEN(lw,'CON:'lw_xs'/'lw_ys'/'c'/'d'/CD-List')
END
ELSE
OPEN(lw,"*")
WRITELN(lw,'')
WRITELN(lw," Titel | Länge")
WRITELN(lw,"--------------------")
DO a = 1 to anz_titel
WRITELN(lw, INSERT('','',0,5-(a > 9),' ')||cd.a.nr" - "cd.a.zeit)
END /* Do */
WRITELN(lw,"--------------------")
WRITELN(lw," Gesamt: "cd.a.zeit)
END
/** 2. Titel zum abspeichern auswaehlen **/
akt_t = 0
rip.0.cdt = "dummy"
gr = 0
/* titel zum Abspeichern holen bis keine Eingabe mehr */
SAY
SAY "Erlaubte Eingaben: 1-"anz_titel", b = letzten Titel löschen, nur Return = ende"
SAY
DO UNTIL rip.akt_t.cdt==""
akt_t = akt_t +1
WRITECH(stdout,"> Bitte "akt_t". gewünschten Titel eingeben: ")
PULL rip.akt_t.cdt
/* evt. eingegebener Abzug vom Leadout auswerten */
IF LEFT(rip.akt_t.cdt,1) == "-" THEN DO
/* leadout abzug vom Titel trennen */
PARSE VALUE rip.akt_t.cdt WITH cut' 'temp
IF temp == "" THEN /* Titel vergessen oder falsch eingegeben */
rip.akt_t.cdt = "X"
ELSE DO
rip.akt_t.cdt = temp /* titel wieder eintragen */
cut = TRANSLATE(cut,'.',',') /* komma durch punkt ersetzten wenn vorhanden */
/* und neuen zusätzlichen abzug ausrechnen. Scheint insgesamt etwas kompliziert, aber so kann ich mehr oder
weniger als den standardabzug abschneiden */
rip.akt_t.cut_lo = ((cut * -75) % 1) - skip_lo
/* abzug + standardabzug dürfen natürlich nicht länger als der titel sein */
IF (rip.akt_t.cut_lo + skip_lo) > cd.temp.laenge THEN DO
SAY "> Scherzkeks, das machen wir nochmal..."
rip.akt_t.cut_lo = 0
rip.akt_t.cdt = "X"
END /* if */
IF debug == 1 THEN
SAY "Abzug: "cut" Titel: "temp" zus.Abzug: "rip.akt_t.cut_lo" Standardabz.: "skip_lo
END /* if temp */
END /* if left */
ELSE
rip.akt_t.cut_lo = 0 /* ohne Eingabe standardabzug nicht ändern */
/* Eingabe erfolgt oder -> eingabeende ? */
IF rip.akt_t.cdt ~== "" THEN DO
/* erstmal schauen ob wir den Titel nicht schon hatten. Geht auch eleganter aber es sind */
/* ja höchstens 20 Titel */
DO a = 1 TO (akt_t -1)
IF rip.akt_t.cdt == rip.a.cdt THEN DO
SAY ">>>> Also den Titel hatten wir schon mal."
SAY
rip.akt_t.cdt = "X" /* X ist eine ungültige Angabe und wird im Select entsprechend behandelt */
END /* if rip.. */
END /* do a */
SELECT
/* Titel im erlaubten Bereich ? */
WHEN (rip.akt_t.cdt >= 1) & (rip.akt_t.cdt <= anz_titel) THEN DO
a = rip.akt_t.cdt
IF cdid_mode == 1 THEN /* zugehörenden mp3-namen generieren */
IF LENGTH(cd.a.cdn) > max_name_len-4 THEN /* genug Platz für extension ? */
rip.akt_t.mpn = LEFT(cd.a.cdn, max_name_len-4)||".mp3"
ELSE
rip.akt_t.mpn = cd.a.cdn||".mp3"
ELSE /* if cdid_mode */
rip.akt_t.mpn = "Titel"rip.akt_t.cdt".mp3" /* zugehörenden default mp3-namen generieren */
/* Vorabinfo wieviel Platz ca. benötigt wird */
gr = gr + (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576)
SAY "> benötigter Speicherplatz bis jetzt ca. "gr" MB."
SAY
END /* when */
/* letzte Eingabe löschen */
WHEN (rip.akt_t.cdt == "B") & (akt_t > 1) THEN DO
akt_t = akt_t -2 /* laufvariable zurücksetzen */
/* Speicheranzeige korrigieren und neu ausgeben, gibt natürlich Rundungsfehler ist aber eh' nur ca. */
a = rip.akt_t.cdt
gr = gr - (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576) + 1
SAY "> benötigter Speicherplatz neu jetzt ca. "gr" MB."
SAY
END /* when */
/* falsche Eingabe */
OTHERWISE
akt_t = akt_t -1 /* laufvariable wieder zurücksetzen */
END /* Select */
END /* if rip.. */
END /* Do until */
CLOSE(lw) /* CD Window wieder schliessen */
anz_save = akt_t -1
/* Titel ausgewählt? */
IF anz_save > 0 THEN DO
/* ermitteln ob auch mp3 erzeugt werden soll */
SAY
WRITECH(stdout,"> Sollen die Songs auch gleich ins mp3-Format umgewandelt werden (j/N)? : ")
PULL mp3
IF mp3 == "J" THEN DO
IF cdid_mode == 0 THEN DO
/* filenamen für mp3-files ermitteln. Bei vorhandenen cdids wUrden die Namen automatisch generiert.
Prinzipiell können auch noch Pfadangaben vor dem Filenamen erfolgen solange die max. Länge von
26 Zeichen nicht überschritten wird (dir/dir/name).
Einfacher ist es aber den globalen Pfad richtig einzustellen.
Überprüfung der Gültigkeit:
FFS max 30 Zeichen (26 + .mp3 = 30)
keine ~ % # ? < > | ( ) [ ] " Zeichen
*/
a = 0
b = ""
/* Die Eingabe der Dateinnamen kann nicht mit Pull erfolgen da dabei alles in Grossbuchstaben
umgewandelt wird. Der einzige mir bekannte Weg dies ohne CON: zu umgehen, ist das Einlesen mit Parse
aus STDERR. Kollidiert allerdings mit evt. offenen Debug-Fenstern
*/
CALL OPEN(STDERR, "*", 'R')
DO UNTIL a == anz_save
a = a +1
SAY
SAY "> Dateiname für mp3-file von Titel "rip.a.cdt" eingeben (ohne extension, default = "rip.a.mpn") : "
PARSE EXTERNAL b
/* wenn ein Name eingegeben wurde diesen uebernehmen ansonsten den defaultnamen verwenden */
IF b ~== "" THEN DO
temp = b
b = create_name(b, max_name_len - LENGTH(mp_ext))
IF b ~== temp THEN DO
SAY
SAY "> Dateiname angepasst:" b
END /* if b/temp */
rip.a.mpn = b||mp_ext
END /* if b/"" */
END /* Do until */
CLOSE(STDERR) /* wir sind ein ordentliches Völkchen ;-) */
END /* if cdid_mode */
END /* if mp3 */
END /* if anz_save */
END /* if anz_titel */
END /* if restore */
/** jetzt kommt sie eigentliche Arbeit, natürlich nur wenn auch Titel ausgewählt wurden **/
IF anz_save > 0 THEN DO
/* bei restore wird gleich begonnen, ansonsten erfolgt abfrage ob die angaben nur gespeichert werden sollen.
Damit kann während eine CD bearbeitet wird bereits die nächste vorbereiten. Skript dann mit Dateinamen starten. */
IF restore ~== "J" THEN DO
WRITECH(stdout,"> Gleich mit der Bearbeitung beginnen oder Angaben nur speichern (g/S)? ")
PULL doit
END /* if restore */
ELSE
doit = "G"
IF doit == "G" THEN DO
/* erstmal bisherige Angaben speichern. Abspeichern erfolgt erst jetzt da es bei späterer bearbeitung nicht
nötig ist die Daten unter dem Backupnamen zu speichern, evt. würde das auch mit einer gerade laufenden
Sitzung kollidieren. Tut es zwar auch wenn eine Instanz gerade mp3 erzeugt und die neue nur cd-files, aber
einen Tod muss man sterben. Wenn ich erst nach dem Erzeugen der CD-files abspeichere ist das Risiko zu gross
dass die Daten durch Absturz verlorengehen. (die ca. 50 MB einer Datei quälen sich bei mir in ca. 40s.
auf die Platte.)
*/
CALL save_datei(titellist,1,anz_save) /* Titelliste für restore abspeichern */
a=1
SAY
/* alle Titel erstmal auf HD speichern. Keine Abfrage auf ausreichend freien Speicherplatz. Wüsste nicht wie */
DO WHILE a <= anz_save
akt_t = rip.a.cdt
cd.akt_t.laenge = cd.akt_t.laenge - rip.a.cut_lo /* titellaenge um evt. eingegebenen abzug korrigieren */
gr = (cd.akt_t.laenge * bpb) % 1048576 /* nur ca-Wert */
SAY "> Speichere Lied Nr." akt_t" als "titelpfad||cd.akt_t.cdn", Grösse ca. "gr" MB"
/* CD-Titel einlesen und abspeichern */
IF debug == 1 THEN
SAY "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
ELSE
ADDRESS COMMAND "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
a = a +1
END /* Do while */
SAY
SAY "> CD wird nicht mehr benötigt"
/* ggf. mp3-files erzeugen */
IF mp3 == "J" THEN DO
SAY
SAY "> erzeuge jetzt die entsprechenden mp3-files ->"
a = 1
DO WHILE a <= anz_save
b = rip.a.cdt
SAY
SAY "> Titel Nr." b "unter "mp3pfad||rip.a.mpn
SAY
/* mp3 erzeugen */
IF debug == 1 THEN DO
SAY "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
SAY "pegase "pegaseopt "FROM "'"'titelpfad||cd.b.cdn'"'" TO "'"'mp3pfad||rip.a.mpn'"'
END
ELSE
SELECT
WHEN encoder == "lame" THEN DO /* Lame ... */
IF lame_ppc == "1" THEN DO /* (PPC-Lame setzt den Stack nicht selbst, daher bauen wir uns */
OPEN(ns,"T:ns",W) /* eine Batchdatei, etwas tricky aber es funktioniert) */
WRITELN(ns, "stack "ppc_stack)
WRITELN(ns, "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"')
CLOSE(ns)
ADDRESS COMMAND "Execute T:ns" /* Batch starten */
ADDRESS COMMAND "Delete >NIL: T:ns" /* und schnell löschen, bevor es jemand sieht */
END
ELSE /* 68k-Lame kümmert sich selbst um den Stack, danke */
ADDRESS COMMAND "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
END
WHEN encoder == "pegase" THEN /* ... oder Pegase. Das ist hier die Frage */
ADDRESS COMMAND "pegase "pegaseopt "FROM "'"'titelpfad||cd.b.cdn'"'" TO "'"'mp3pfad||rip.a.mpn'"'
OTHERWISE
SAY "Oops, unknown encoder, please check the parameters"
END /* select */
CALL save_datei(titellist,a+1,anz_save) /* fertige files aus abgespeicherter Titelliste entfernen */
/* CD-file löschen */
IF debug == 1 THEN
SAY "Delete" '"'titelpfad||cd.b.cdn'"'
IF (debug == 0) & (del_titel == 1) THEN
ADDRESS COMMAND "Delete >NIL: "'"'titelpfad||cd.b.cdn'"'
a = a +1
END /* Do while */
END /* If mp3 */
ELSE /* wenn nur Audio-Dateien erzeugt wurden wird titelliste nicht mehr gebraucht */
ADDRESS COMMAND "Delete >NIL: "'"'titelpfad||titellist'"'
END /* if doit */
ELSE DO /* if doit - Daten für spätere Bearbeitung speichern */
/* Dateiname mit CD-Titel oder Defaultname vorbelegen */
IF cdid_mode == 1 THEN
listname = cd.0.name
ELSE
listname = cdsave
listname = create_name(listname, max_name_len) /* an Dos anpassen */
/* und fragen ob's dem Herrn Anwender gefällt */
SAY
SAY "> Bitte Dateinamen zum Abspeichern der Titelliste eingeben."
SAY "> (default="listname"):"
PULL a
IF a ~== "" THEN DO /* check ob neuer name eingegeben wurde, wenn ja diesen verwenden */
listname = a
listname = create_name(listname, max_name_len) /* neuen Namen an Dos anpassen */
END
SAY
SAY "> Danke, Titelliste wird unter <"listname"> gespeichert."
SAY "> Sobald die Liste bearbeitet werden soll, cdmp.rx mit"
SAY "> diesem Namen als Parameter starten."
SAY "> Also: cdmp.rx "listname
CALL save_datei(listname,1,anz_save)
END /* Else - if doit */
END /* If anz_save */
SAY
SAY "> Ok, das war's und tschüssss........"
SAY
ende:
ADDRESS COMMAND "WAIT 5"
EXIT
/**********************/
/**** Sub-routinen ****/
/**********************/
/****
save_datei - speichert unter dem angebenen Dateinamen die Variablen cdid, mp3 und den Inhalt der rip-Variablen
von 'start' bis 'ende' im zugewiesenen Datenverzeichnis.
Keine Fehlerabfrage - zuviel Aufwand für relativ unwichtige Daten
template: save_datei(datei,start,ende)
****/
save_datei:
PARSE ARG sdatei, sstart, sende
IF sstart > sende THEN ADDRESS COMMAND "Delete >NIL: "titelpfad||sdatei
ELSE DO
OPEN(datei_out,titelpfad||sdatei,W)
WRITELN(datei_out, cdid)
WRITELN(datei_out, mp3)
DO sa = sstart TO sende
IF debug == 1 THEN SAY "Speichere "rip.sa.cdt", "rip.sa.mpn", "rip.sa.cut_lo
WRITELN(datei_out, rip.sa.cdt)
WRITELN(datei_out, rip.sa.mpn)
WRITELN(datei_out, rip.sa.cut_lo)
END /* do sa */
CLOSE(datei_out)
END /* else */
RETURN
/* ---------------------------- */
/****
create_id - erzeugt einen CDID String.
globalen Variablen: anz_titel und cd.
lokale VAriablen : sa
****/
create_id:
sa = "ID"
IF anz_titel > 9 THEN
sa = sa||anz_titel
ELSE
sa = sa||'0'||anz_titel
IF anz_titel == 2 THEN /* kann man Singles mit 'nem CD-Rom lesen ? na, sicher ist sicher */
sa = sa||D2X(cd.anz_titel.ende+1,6)||D2X(cd.anz_titel.ende+1,6)
ELSE
sa = sa||D2X(cd.3.start,6)||D2X(cd.anz_titel.ende+1,6)
IF debug == 1 THEN SAY sa
RETURN sa
/* ---------------------------- */
/****
get_toc - liest und überträgt das Inhaltsverzeichnis der CD.
globale Variablen: cd., akt_titel, cdlist, anz_titel, cdid, cdid_mode
lokale Variablen : datei_in, zeile, akt_t, cdnr, dummy
****/
get_toc:
ADDRESS COMMAND "cdda plan="plan" list >"cdlist
IF EXISTS(cdlist) THEN DO
OPEN(datei_in,cdlist,R)
/* 1.Zeile -> wegschmeissen) */
zeile = READLN(datei_in)
akt_t = 0
cdnr = ""
/* titel einlesen bis total oder eof erreicht */
DO WHILE ( (cdnr ~== "TOT:") & ~eof(datei_in) )
/* 2.+...Zeile -> einlesen und auswerten) */
zeile = READLN(datei_in)
/* laufvariable fuer stamm */
akt_t = akt_t +1
cd.akt_t.nr = akt_t
cd.akt_t.cdn = "Titel"akt_t
/* in teilstrings zerlegen, unwichtiges mit dummy wegwerfen */
PARSE VALUE zeile WITH cdnr cd.akt_t.start dummy cd.akt_t.ende dummy cd.akt_t.laenge cd.akt_t.zeit dummy
cd.akt_t.laenge = cd.akt_t.laenge - skip_lo /* Leadout kürzen */
cd.akt_t.zeit = SUBSTR(cd.akt_t.zeit, 2, 8)
IF debug == 1
THEN say cd.akt_t.nr": " cdnr cd.akt_t.start cd.akt_t.ende cd.akt_t.laenge cd.akt_t.zeit dummy
END /* do while */
CLOSE(datei_in)
ADDRESS COMMAND "Delete >NIL: "'"'cdlist'"' /* liste wird nicht mehr gebraucht */
END /* if exists */
anz_titel = akt_t -1
SELECT
WHEN anz_titel < 1 THEN DO
SAY
SAY "> Hmmm, keine CD im Laufwerk oder Device/Unit falsch oder belegt!"
END
WHEN anz_titel == 1 THEN DO /* ich geh' mal davon aus das es keine Audio-Cds mit einem Titel gibt */
SAY
SAY "> Hmmm, scheint sich um eine Daten-CD zu handeln"
anz_titel = -1
END
WHEN anz_titel > 1 THEN DO
cdid = create_id()
IF cdid_mode == 1 THEN
CALL read_cdid()
END
END /* select */
RETURN
/* ---------------------------- */
/****
get_cdname - liest vorhandene cdid daten ein und wertet sie aus
globalen Variablen: anz_titel, cdid_dir, cdid, max_nam_len und cd.
lokale variablen : datei_in, akt_t, zeile, sa,
****/
read_cdid:
IF EXISTS(cdid_dir||cdid) THEN DO
OPEN(datei_in,cdid_dir||cdid,R)
akt_t = 0
/* cd.0. enthält die globalen CD Daten */
cd.0.ip = READLN(datei_in) /* 1.Zeile -> Interpret der CD */
cd.0.name = READLN(datei_in) /* 2.Zeile -> CD-Name */
/* titel einlesen bis eof erreicht */
DO WHILE (~eof(datei_in))
akt_t = akt_t +1
zeile = STRIP(READLN(datei_in)) /* zeile einlesen und führende und nachgestellte Leerzeichen entfernen */
sa = POS('B7'x,zeile) /* nach · suchen - trennt interpret und titel bei Samplern */
IF sa > 0 THEN DO
cd.akt_t.ip = STRIP(LEFT(zeile,sa-1)) /* links davon ist der Interpret */
cd.akt_t.name = STRIP(SUBSTR(zeile,sa+1)) /* rechts der Titel */
END
ELSE DO /* kein Sampler, Interpret ist für alle Titel derselbe */
cd.akt_t.ip = cd.0.ip
cd.akt_t.name = zeile
END
cd.akt_t.cdn = create_name(cd.akt_t.name, max_name_len) /* entspr. Dateinamen generieren */
IF debug == 1
THEN say cd.akt_t.nr": " zeile sa cd.akt_t.ip cd.akt_t.name cd.akt_t.cdn
END /* do while */
CLOSE(datei_in)
END
ELSE
cdid_mode = 0
RETURN
/* ---------------------------- */
/****
create_name - erzeugt aus einem übergebenen String und der max. Länge einen korrekten
Dos-namen.
globalen Variablen: dirty_char, repl_spc.
lokale variablen : s_name, s_len
****/
create_name:
PARSE ARG s_name, s_len
IF LENGTH(s_name) > s_len THEN /* Dateinamenlänge prüfen und korrigieren */
s_name = LEFT(s_name,s_len)
s_name = TRANSLATE(s_name,'',dirty_char,'_') /* Zeichen die mit Dos kollidieren durch Unterstrich ersetzen */
IF (repl_spc == 1) THEN
s_name = TRANSLATE(s_name,'_',' ') /* eingegebene Leerzeichen durch Unterstrich ersetzten falls erwünscht */
RETURN s_name
/* ---------------------------- */
/** CTRL-C Behandlung **/
break_c:
failure:
SAY ">>> Bearbeitung abgebrochen"
SIGNAL ende
/* ---------------------------- */